package com.gitee.melin.bee.core.jdbc;

import com.gitee.melin.bee.core.jdbc.dialect.JdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.cassandra.CassandraJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.clickhouse.ClickHouseJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.db2.DB2JdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.dm.DaMengJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.doris.DorisJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.hana.SapHanaJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.hive.HiveJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.impala.ImpalaJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.inceptor.InceptorJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.maxcompute.MaxComputeJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.mysql.MySqlJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.oceanbase.OceanBaseJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.oracle.OracleJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.phoenix.PhoenixJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.postgres.PostgreSqlJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.redshift.RedshiftJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.sqlserver.SqlServerJdbcDialect;
import com.gitee.melin.bee.core.jdbc.dialect.starrocks.StarRocksJdbcDialect;
import com.gitee.melin.bee.core.jdbc.enums.DataSourceType;
import com.gitee.melin.bee.core.jdbc.relational.ConnectionInfo;
import com.google.common.collect.Maps;

import java.sql.Connection;
import java.util.concurrent.ConcurrentMap;

public class JdbcDialectHolder {

    private static final ConcurrentMap<ConnectionInfo, JdbcDialect> concurrentMap = Maps.newConcurrentMap();

    public static JdbcDialect getJdbcDialect(ConnectionInfo dataConnectionInfo) {
        DataSourceType dataSourceType = dataConnectionInfo.getDataSourceType();

        return concurrentMap.computeIfAbsent(dataConnectionInfo, connector -> {
            if (DataSourceType.MYSQL == dataSourceType || DataSourceType.TIDB == dataSourceType) {
                return new MySqlJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.DORIS == dataSourceType) {
                return new DorisJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.STARROCKS == dataSourceType) {
                return new StarRocksJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.POSTGRESQL == dataSourceType || DataSourceType.GAUSS == dataSourceType) {
                return new PostgreSqlJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.ORACLE == dataSourceType) {
                return new OracleJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.SQLSERVER == dataSourceType) {
                return new SqlServerJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.DB2 == dataSourceType) {
                return new DB2JdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.HANA == dataSourceType) {
                return new SapHanaJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.HIVE == dataSourceType) {
                return new HiveJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.IMPALA == dataSourceType) {
                return new ImpalaJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.INCEPTOR == dataSourceType) {
                return new InceptorJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.PHOENIX == dataSourceType) {
                return new PhoenixJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.DAMENG == dataSourceType) {
                return new DaMengJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.OCEANBASE == dataSourceType) {
                return new OceanBaseJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.CLICKHOUSE == dataSourceType) {
                return new ClickHouseJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.CASSANDRA == dataSourceType) {
                return new CassandraJdbcDialect(dataConnectionInfo);
            } else if (DataSourceType.REDSHIFT == dataSourceType) {
                return new RedshiftJdbcDialect(dataConnectionInfo);
            } else {
                throw new IllegalArgumentException("不支持数据源: " + dataSourceType);
            }
        });
    }

    public static JdbcDialect getJdbcDialect(DataSourceType dataSourceType, Connection connection) {
        if (DataSourceType.MYSQL == dataSourceType || DataSourceType.TIDB == dataSourceType
                || DataSourceType.DORIS == dataSourceType || DataSourceType.STARROCKS == dataSourceType) {
            return new MySqlJdbcDialect(connection);
        } else if (DataSourceType.POSTGRESQL == dataSourceType || DataSourceType.GAUSS == dataSourceType) {
            return new PostgreSqlJdbcDialect(connection);
        } else if (DataSourceType.ORACLE == dataSourceType) {
            return new OracleJdbcDialect(connection);
        } else if (DataSourceType.SQLSERVER == dataSourceType) {
            return new SqlServerJdbcDialect(connection);
        } else if (DataSourceType.DB2 == dataSourceType) {
            return new DB2JdbcDialect(connection);
        } else if (DataSourceType.HANA == dataSourceType) {
            return new SapHanaJdbcDialect(connection);
        } else if (DataSourceType.HIVE == dataSourceType) {
            return new HiveJdbcDialect(connection);
        } else if (DataSourceType.IMPALA == dataSourceType) {
            return new ImpalaJdbcDialect(connection);
        } else if (DataSourceType.INCEPTOR == dataSourceType) {
            return new InceptorJdbcDialect(connection);
        } else if (DataSourceType.PHOENIX == dataSourceType) {
            return new PhoenixJdbcDialect(connection);
        } else if (DataSourceType.DAMENG == dataSourceType) {
            return new DaMengJdbcDialect(connection);
        } else if (DataSourceType.OCEANBASE == dataSourceType) {
            return new OceanBaseJdbcDialect(connection);
        } else if (DataSourceType.MAXCOMPUTE == dataSourceType) {
            return new MaxComputeJdbcDialect(connection);
        } else if (DataSourceType.CLICKHOUSE == dataSourceType) {
            return new ClickHouseJdbcDialect(connection);
        } else if (DataSourceType.CASSANDRA == dataSourceType) {
            return new CassandraJdbcDialect(connection);
        } else if (DataSourceType.REDSHIFT == dataSourceType) {
            return new RedshiftJdbcDialect(connection);
        } else {
            throw new IllegalArgumentException("不支持数据源: " + dataSourceType);
        }
    }
}
